package com.yxhl.zoume.core.func.pay.fragment;

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RelativeLayout;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.jakewharton.rxbinding.view.RxView;
import com.yxhl.zoume.R;
import com.yxhl.zoume.SpecialCarPaymentDataBinding;
import com.yxhl.zoume.common.ui.fragment.BaseDataBindingFragment;
import com.yxhl.zoume.core.coupon.model.CouponSelectEvent;
import com.yxhl.zoume.core.coupon.model.CouponSelectModel;
import com.yxhl.zoume.core.coupon.model.CouponUseStatusEnum;
import com.yxhl.zoume.core.func.appraisal.model.AppraisalDriverInfo;
import com.yxhl.zoume.core.func.pay.activity.CarPaymentActivity;
import com.yxhl.zoume.core.func.pay.model.event.ExpressCarBillDetailEvent;
import com.yxhl.zoume.core.func.pay.presenter.AliPayPresenter;
import com.yxhl.zoume.core.func.pay.presenter.WalletPayPresenter;
import com.yxhl.zoume.core.func.pay.presenter.WeChatPayPresenter;
import com.yxhl.zoume.core.func.pay.view.AliPayView;
import com.yxhl.zoume.core.func.pay.view.WalletPayView;
import com.yxhl.zoume.core.func.pay.view.WeChatPayView;
import com.yxhl.zoume.core.specialcar.model.CarPaymentInfo;
import com.yxhl.zoume.core.specialcar.model.CashStatus;
import com.yxhl.zoume.core.specialcar.model.SpecialCarFeeDetailModel;
import com.yxhl.zoume.core.specialcar.model.SpecialCarPaymentEnum;
import com.yxhl.zoume.core.specialcar.presenter.SpecialCarCashPayPresenter;
import com.yxhl.zoume.core.specialcar.presenter.SpecialCarPayPresenter;
import com.yxhl.zoume.core.specialcar.view.SpecialCarCashPayView;
import com.yxhl.zoume.core.specialcar.view.SpecialCarPayView;
import com.yxhl.zoume.data.http.model.coupon.CouponInfo;
import com.yxhl.zoume.data.rxbus.RxBus;
import com.yxhl.zoume.di.component.car.SpecialCarPayComponent;
import com.yxhl.zoume.utils.LOG;
import com.yxhl.zoume.utils.PromptUtils;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import rx.functions.Action1;

/**
 * Created by vhawk on 2016/10/11.
 */
public class CarPayFragment extends BaseDataBindingFragment implements AliPayView, WeChatPayView, SpecialCarCashPayView, SpecialCarPayView, WalletPayView {

    private static final String KEY_PAYMENT_INFO = "PAYMENT_INFO";
    private static final String TAG = "CarPayFragment";
    /**
     * 支付宝支付presenter
     */
    @Inject
    public AliPayPresenter aliPayPresenter;
    /**
     * 微信支付presenter
     */
    @Inject
    public WeChatPayPresenter weChatPayPresenter;
    @Inject
    SpecialCarCashPayPresenter carCashPayPresenter;
    /**
     * 获取订单信息
     */
    @Inject
    SpecialCarPayPresenter specialCarPayPresenter;
    @Inject
    WalletPayPresenter walletPayPresenter;
    MaterialDialog dialogForWaitingPayment;
    @BindView(R.id.rl_coupon_content)
    RelativeLayout couponContentRl;
    @BindView(R.id.rl_raw_fee)
    RelativeLayout originalFeeRl;
    private SpecialCarPaymentDataBinding specialCarPaymentDataBinding;
    private SpecialCarPaymentEnum paymentEnum = SpecialCarPaymentEnum.SPECIAL_CAR_PAYMENT_ENUM_ALI;
    private SpecialCarPayComponent component;
    private CarPaymentInfo paymentInfo;
    private CouponInfo couponInfo;
    private CouponUseStatusEnum couponUseStatusEnum = CouponUseStatusEnum.COUPON_USE_STATUS_ENUM_NONE;

    public static Fragment newInstance(CarPaymentInfo paymentInfo) {
        CarPayFragment fragment = new CarPayFragment();
        Bundle bundle = new Bundle();
        bundle.putSerializable(KEY_PAYMENT_INFO, paymentInfo);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        handleExtraParam();
        specialCarPaymentDataBinding.setPaymentInfo(paymentInfo);
        specialCarPaymentDataBinding.setCashStatus(new CashStatus().setCashShowStatus(false));
        //presenter attach view
        aliPayPresenter.attachView(this);
        weChatPayPresenter.attachView(this);
        carCashPayPresenter.attachView(this);
        specialCarPayPresenter.attachView(this);
        walletPayPresenter.attachView(this);
        //fetch best coupon
        specialCarPayPresenter.fetchSpecialCarPayInfo(paymentInfo.getBizType(), paymentInfo.getTotalFee(), null);
        registerClickEvent();
        onRxBusEvent();
    }

    @Override
    public void onResume() {
        super.onResume();
        ((CarPaymentActivity)component.context()).setToolbarTitle("订单支付");
        aliPayPresenter.onResume();
        weChatPayPresenter.onResume();
        carCashPayPresenter.onResume();
        specialCarPayPresenter.onResume();
        walletPayPresenter.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        aliPayPresenter.onPause();
        weChatPayPresenter.onPause();
        carCashPayPresenter.onPause();
        specialCarPayPresenter.onPause();
        walletPayPresenter.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        aliPayPresenter.onDestroy();
        weChatPayPresenter.onDestroy();
        carCashPayPresenter.onDestroy();
        specialCarPayPresenter.onDestroy();
        walletPayPresenter.onDestroy();
    }


    private void onRxBusEvent() {
        getSubscription().add(toSubscription(CouponSelectEvent.class, new Action1<CouponSelectEvent>() {
            @Override
            public void call(CouponSelectEvent couponSelectEvent) {
                if (CouponUseStatusEnum.COUPON_USE_STATUS_ENUM_UNUSED == couponSelectEvent.getCouponUseStatusEnum()) {
                    couponUseStatusEnum = CouponUseStatusEnum.COUPON_USE_STATUS_ENUM_UNUSED;
                    specialCarPaymentDataBinding.setCouponUseStatusEnum(couponUseStatusEnum);
                    couponInfo = new CouponInfo();
                    couponInfo.setTotalFee(Double.parseDouble(paymentInfo.getTotalFee()))
                            .setOrderTotalFee(paymentInfo.getTotalFee())
                            .setDiscountFee(0);
                    specialCarPaymentDataBinding.setCouponInfo(couponInfo);
                } else {
                    specialCarPayPresenter.fetchSpecialCarPayInfo(paymentInfo.getBizType(), paymentInfo.getTotalFee(), couponSelectEvent.getCouponId());
                }
            }
        }));
    }


    private void handleExtraParam() {
        Bundle arguments = getArguments();
        paymentInfo = (CarPaymentInfo) arguments.getSerializable(KEY_PAYMENT_INFO);
    }

    @Override
    protected void initializeInjector() {
        component = getComponent(SpecialCarPayComponent.class);
        component.inject(this);
    }

    @Override
    protected View getContentLayout(LayoutInflater inflater, ViewGroup container) {
        specialCarPaymentDataBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_special_car_payment, container, false);
        return specialCarPaymentDataBinding.getRoot();
    }

    @Override
    protected void setupToolBar() {

    }

    private void registerClickEvent() {
        RxView.clicks(couponContentRl).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                if (couponUseStatusEnum != CouponUseStatusEnum.COUPON_USE_STATUS_ENUM_NONE) {
                    CouponSelectModel couponSelectModel = new CouponSelectModel();
                    couponSelectModel.setBizType(paymentInfo.getBizType())
                            .setOrderTotalFee(paymentInfo.getTotalFee())
                            .setCouponUserRelId(couponInfo.getUserCouponId() + "");
                    getAppComponent().navigator().navigateToCouponSelectPage((CarPaymentActivity) component.context(), couponSelectModel);
                }
            }
        });

        RxView.clicks(originalFeeRl).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {

                switch (paymentInfo.getCarPaymentEntrance()) {
                    case CAR_PAYMENT_ENTRANCE_SPECIAL_CAR_SHARE:
                    case CAR_PAYMENT_ENTRANCE_SPECIAL_CAR_CHARTER:
                        navigateToSpecialCarBillDetail();
                        break;

                    case CAR_PAYMENT_ENTRANCE_EXPRESS_CAR_TIME:
                    case CAR_PAYMENT_ENTRANCE_EXPRESS_CAR_WAY:
                        navigateToExpressCarBillDetail();
                        break;
                }
            }
        });
    }

    private void navigateToExpressCarBillDetail() {
        ExpressCarBillDetailEvent event = new ExpressCarBillDetailEvent();
        event.setOrderSerial(paymentInfo.getOrderId())
                .setTotalFee(paymentInfo.getTotalFee())
                .setDiscountFee(couponInfo.getDiscountFee() + "");
        RxBus.getInstance().send(event);
    }

    private void navigateToSpecialCarBillDetail() {
        SpecialCarFeeDetailModel feeDetailModel = new SpecialCarFeeDetailModel();
        feeDetailModel.setCouponFee(couponInfo.getDiscountFee() + "")
                .setCouponName(couponInfo.getCouponName())
                .setOriginalFee(couponInfo.getOrderTotalFee() + "")
                .setTotalFee(couponInfo.getTotalFee() + "");
        getAppComponent().navigator().navigateToSpecialCarPayDetail((CarPaymentActivity) component.context(), feeDetailModel);
    }

    @OnClick({R.id.rb_wallet_pay, R.id.rb_ali_pay, R.id.rb_we_chat_pay, R.id.rb_crash_pay})
    public void onPaymentWayChanged(RadioButton radioButton) {
        switch (radioButton.getId()) {
            case R.id.rb_wallet_pay:
                paymentEnum = SpecialCarPaymentEnum.SPECIAL_CAR_PAYMENT_ENUM_WALLET;
                break;
            case R.id.rb_ali_pay:
                paymentEnum = SpecialCarPaymentEnum.SPECIAL_CAR_PAYMENT_ENUM_ALI;
                LOG.v(TAG, "paymentEnum = " + paymentEnum);
                break;

            case R.id.rb_we_chat_pay:
                paymentEnum = SpecialCarPaymentEnum.SPECIAL_CAR_PAYMENT_ENUM_WE_CHAT;
                LOG.v(TAG, "paymentEnum = " + paymentEnum);
                break;

            case R.id.rb_crash_pay:
                paymentEnum = SpecialCarPaymentEnum.SPECIAL_CAR_PAYMENT_ENUM_CASH;
                LOG.v(TAG, "paymentEnum = " + paymentEnum);
                break;
        }
    }

    @OnClick(R.id.tv_more_pay_way)
    public void onMorePaymentWayClick() {
        specialCarPaymentDataBinding.setCashStatus(new CashStatus().setCashShowStatus(true));
    }

    @OnClick(R.id.bt_confirm)
    public void payConfirm() {
        LOG.v(TAG, "paymentEnum = " + paymentEnum);
        switch (paymentEnum) {
            case SPECIAL_CAR_PAYMENT_ENUM_ALI:
                aliPayPresenter.getSignedStr(component.context(), paymentInfo.getTotalFee(), paymentInfo.getOrderId(), couponInfo.getUserCouponId() + "", couponInfo.getDiscountFee() + "");
                break;
            case SPECIAL_CAR_PAYMENT_ENUM_WE_CHAT:
                weChatPayPresenter.getWeChatPayOrderInfo(component.context(), paymentInfo.getOrderId(), couponInfo.getUserCouponId() + "", couponInfo.getDiscountFee() + "");
                break;
            case SPECIAL_CAR_PAYMENT_ENUM_CASH:
                carCashPayPresenter.payByCash(paymentInfo.getOrderId());
                break;
            case SPECIAL_CAR_PAYMENT_ENUM_WALLET:
                walletPayPresenter.payByWallet(paymentInfo.getOrderId(), couponInfo.getUserCouponId() + "", couponInfo.getDiscountFee() + "");
                break;
        }
    }

    @Override
    public void renderAliPaySucceed() {
        paySucceed();
    }

    @Override
    public void renderAliPayFailure(String resultStatus) {
        PromptUtils.showShort(component.context(), resultStatus);
    }

    @Override
    public void renderAliPaySignedError() {
        PromptUtils.showShort(component.context(), R.string.net_error);
    }

    @Override
    public void dismissWaitingDialog() {
        waitingForPayment(false);
    }

    @Override
    public void showErrorMessage(String errorMessage) {
        waitingForPayment(false);
        PromptUtils.showShort(component.context(), errorMessage);
    }

    @Override
    public void showWechatUninstalledDialog() {
        waitingForPayment(false);

        new MaterialDialog.Builder(component.context())
                .content(R.string.hint_wechat_uninstalled)
                .positiveText(R.string.dialog_confirm)
                .positiveColorRes(R.color.app_primary_blue)
                .canceledOnTouchOutside(false)
                .show();

        new MaterialDialog.Builder(component.context())
                .onPositive(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        dialog.dismiss();
                    }
                });
    }

    /**
     * 等待支付
     *
     * @param isWaiting
     */
    public void waitingForPayment(boolean isWaiting) {
        if (isWaiting) {
            dialogForWaitingPayment = new MaterialDialog.Builder(component.context())
                    .content(R.string.dialog_waiting_paying)
                    .progress(true, 0)
                    .canceledOnTouchOutside(false)
                    .show();
        } else {
            if (null != dialogForWaitingPayment) {
                dialogForWaitingPayment.dismiss();
            }
        }
    }

    @Override
    public void handleCashPaySucceed() {
        paySucceed();
    }

    @Override
    public void handleCashPayFailure(String msg) {
        PromptUtils.showShort(component.context(), msg);
    }

    @Override
    public void handleCashPayError() {
        PromptUtils.showShort(component.context(), R.string.net_error);
    }

    private void paySucceed() {
        AppraisalDriverInfo driverInfo = new AppraisalDriverInfo();
        driverInfo.setOrderId(paymentInfo.getOrderId())
                .setDriverName(paymentInfo.getDriverName())
                .setPlateNumber(paymentInfo.getPlateNumber())
                .setHistoryScore(paymentInfo.getHistoryScore());

        getAppComponent().navigator().navigateToAppraisal(getActivity(), driverInfo);
        ((CarPaymentActivity) component.context()).finish();
    }

    @Override
    public void handlePayInfoSucceed(CouponInfo couponInfo) {
        if (couponInfo.getUserCouponId() == 0) {
            this.couponInfo = new CouponInfo();
            this.couponInfo.setTotalFee(Double.parseDouble(paymentInfo.getTotalFee()))
                    .setOrderTotalFee(paymentInfo.getTotalFee())
                    .setDiscountFee(0);
            couponUseStatusEnum = CouponUseStatusEnum.COUPON_USE_STATUS_ENUM_NONE;
            specialCarPaymentDataBinding.setCouponUseStatusEnum(couponUseStatusEnum);
            specialCarPaymentDataBinding.setCouponInfo(this.couponInfo);
        } else {
            this.couponInfo = couponInfo;
            couponUseStatusEnum = CouponUseStatusEnum.COUPON_USE_STATUS_ENUM_USED;
            specialCarPaymentDataBinding.setCouponUseStatusEnum(couponUseStatusEnum);
            specialCarPaymentDataBinding.setCouponInfo(couponInfo);
        }
    }

    @Override
    public void handlePayInfoFailure(String msg) {
        PromptUtils.showShort(component.context(), msg);
        getActivity().finish();
    }

    @Override
    public void handlePayInfoError() {
        PromptUtils.showShort(component.context(), R.string.net_error);
    }

    @Override
    public void handleWalletPaySucceed() {
        paySucceed();
    }

    @Override
    public void handleWalletPayFailure(String msg) {
        PromptUtils.showShort(component.context(), msg);
    }

    @Override
    public void handleWalletPayError() {
        PromptUtils.showShort(component.context(), R.string.net_error);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // TODO: inflate a fragment view
        View rootView = super.onCreateView(inflater, container, savedInstanceState);
        ButterKnife.bind(this, rootView);
        return rootView;
    }
}
